package wechat

import (
	"context"
	"encoding/json"

	// "fmt"
	"net/http"

	"mall/common/mqueuex"
	"mall/common/resultx"
	"mall/service/pay/api/internal/svc"
	"mall/service/pay/api/internal/types"

	// "mall/service/pay/rpc/payclient"

	"github.com/pkg/errors"
	// "github.com/sirupsen/logrus"
	"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
	"github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
	"github.com/wechatpay-apiv3/wechatpay-go/core/notify"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments"
	"github.com/zeromicro/go-zero/core/logx"
)

var WechatPayCallbackError = resultx.NewErrCode(resultx.PAYMENT_WECHAT_PAY_CALLBACK_FAIL)

type WechatPayCallbackLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewWechatPayCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WechatPayCallbackLogic {
	return &WechatPayCallbackLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *WechatPayCallbackLogic) WechatPayCallback(req *http.Request) (resp *types.CallbackResponse, err error) {
	// Retrieve the local merchant certificate private key.
	_, err = svc.NewWxPayClientV3(l.svcCtx.Config)
	if err != nil {
		return nil, err
	}

	//Get platform certificate accessor
	//2. 获取商户号对应的微信支付平台证书访问器
	certVisitor := downloader.MgrInstance().GetCertificateVisitor(l.svcCtx.Config.WxPayConf.MchId)
	//3. 使用证书访问器初始化 `notify.Handler`
	handler := notify.NewNotifyHandler(l.svcCtx.Config.WxPayConf.APIv3Key, verifiers.NewSHA256WithRSAVerifier(certVisitor))
	// Verifying signatures, parsing data
	transaction := new(payments.Transaction)
	_, err = handler.ParseNotifyRequest(context.Background(), req, transaction)
	if err != nil {
		return nil, errors.Wrapf(WechatPayCallbackError, "Failed to parse data, err: %v", err)
	}

	returnCode := "SUCCESS"
	// notify  sub "payment-update-tradestate-topic"  services(backend-rmq ..), pub、sub use kq
	if err = l.pubKqPaymentUpdateTradeState(transaction); err != nil {
		// logx.WithContext(l.ctx).Errorf("WechatPayCallback pubKqPaymentUpdateTradeState, err: %+v ", err)
		logx.Errorw("WechatPayCallback pubKqPaymentUpdateTradeState error", logx.Field("detail", err.Error()))
		returnCode = "FAIL"
	}

	return &types.CallbackResponse{
		ReturnCode: returnCode,
	}, err
}

func (l *WechatPayCallbackLogic) pubKqPaymentUpdateTradeState(notifyTransaction *payments.Transaction) error {
	// logrus.Info(fmt.Sprintf("WechatPayCallback pubKqPaymentUpdateTradeState notifyTransaction: %+v", *notifyTransaction))
	// logx.Infof("WechatPayCallback pubKqPaymentUpdateTradeState notifyTransaction: %+v ", *notifyTransaction)
	// Transaction{
	// 	Amount:TransactionAmount{
	// 		Currency:CNY,
	// 		PayerCurrency:CNY,
	// 		PayerTotal:1,
	// 		Total:1
	// 	},
	// 	Appid:wxae04812d377f4f50,
	// 	Attach:爱马仕 李先生的花园,
	// 	BankType:CCB_DEBIT, OTHERS,
	// 	Mchid:1601210629,
	// 	OutTradeNo:PMT2023052917065352845462159,
	// 	Payer:TransactionPayer{
	// 		Openid:o-kUG5pMqzsclBbFlUdZNJ2OW4_o
	// 	},
	// 	PromotionDetail:[],
	// 	SuccessTime:2023-05-29T17:07:04+08:00,
	// 	TradeState:SUCCESS,
	// 	TradeStateDesc:支付成功,
	// 	TradeType:JSAPI,
	// 	TransactionId:4200001864202305296959373020
	// }

	m := mqueuex.ThirdPartPaymentUpdateTradeStateMessage{
		PayerTotal:     notifyTransaction.Amount.PayerTotal,
		Total:          notifyTransaction.Amount.Total,
		OutTradeNo:     notifyTransaction.OutTradeNo,
		TradeState:     notifyTransaction.TradeState,
		TradeStateDesc: notifyTransaction.TradeStateDesc,
		TradeType:      notifyTransaction.TradeType,
		TransactionId:  notifyTransaction.TransactionId,
	}
	body, err := json.Marshal(m)
	if err != nil {
		logx.Errorw("kq WechatPayCallback pushKqPaymentUpdateTradeState json.Marshal error", logx.Field("detail", err.Error()))
		return errors.Wrapf(
			resultx.NewErrCodeMsg(resultx.PAYMENT_WECHAT_PAY_CALLBACK_FAIL, "kq WechatPayCallback pubKqPaymentUpdateTradeState json.Marshal error"),
			"kq WechatPayCallback pushKqPaymentUpdateTradeState json.Marshal error, v: %+v",
			m,
		)
	}

	return l.svcCtx.KqPaymentUpdateTradeStateClient.Push(string(body))
}

// Verify and update relevant flow data
// func (l *WechatPayCallbackLogic) verifyAndUpdateTradeState(notifyTransaction *payments.Transaction) error {
// 	logrus.Info(fmt.Sprintf("WechatPayCallbackLogic verifyAndUpdateTradeState notifyTransaction: %+v", *notifyTransaction))

// 	paymentResp, err := l.svcCtx.PayRpc.GetPaymentBySn(l.ctx, &payclient.GetPaymentBySnRequest{
// 		Sn: *notifyTransaction.OutTradeNo,
// 	})
// 	if err != nil || paymentResp.PaymentDetail.Id == 0 {
// 		return errors.Wrapf(WechatPayCallbackError, "Failed to get payment flow record err: %v , notifyTransaction: %+v ", err, notifyTransaction)
// 	}

// 	// 比对金额
// 	notifyPayTotal := *notifyTransaction.Amount.PayerTotal
// 	if paymentResp.PaymentDetail.PayTotal != notifyPayTotal {
// 		return errors.Wrapf(WechatPayCallbackError, "Order amount exception notifyPayTotal: %v , notifyTransaction: %v ", notifyPayTotal, notifyTrasaction)
// 	}

// 	// Judgment status
// 	payStatus := l.parseTradeStateFromWeChatPayToThirdPartyPayment(*notifyTransaction.TradeState)
// 	if payStatus == mqueuex.ThirdPartyPaymentTradeStateSuccess {
// 		// Payment Notification.
// 		if paymentResp.PaymentDetail.PayStatus != mqueuex.ThirdPartyPaymentTradeStateNotPay {
// 			return nil
// 		}

// 		// Update the flow status.
// 		if _, err = l.svcCtx.PayRpc.UpdateTradeState(l.ctx, &payclient.UpdateTradeStateRequest{
// 			Sn:             *notifyTransaction.OutTradeNo,
// 			TradeState:     *notifyTransaction.TradeState,
// 			TransactionId:  *notifyTransaction.TransactionId,
// 			TradeType:      *notifyTransaction.TradeType,
// 			TradeStateDesc: *notifyTransaction.TradeStateDesc,
// 			PayStatus:      payStatus,
// 		}); err != nil {
// 			return errors.Wrapf(WechatPayCallbackError, "更新流水状态失败  err: %v , notifyTransaction: %v ", err, notifyTransaction)
// 		}

// 	} else if payStatus == mqueuex.ThirdPartyPaymentTradeStateNotPay {
// 		// Refund notification @todo to be done later, not needed at this time
// 	}

// 	return nil
// }

// func (l *WechatPayCallbackLogic) parseTradeStateFromWeChatPayToThirdPartyPayment(weChatPayTradeState string) int32 {
// 	switch weChatPayTradeState {
// 	case mqueuex.WeChatPayTradeStateSuccess: // 支付成功
// 		return mqueuex.ThirdPartyPaymentTradeStateSuccess
// 	case mqueuex.WeChatPayTradeStateUserPaying: // 支付中
// 		return mqueuex.ThirdPartyPaymentTradeStateUserPaying
// 	case mqueuex.WeChatPayTradeStateRefund: // 已退款
// 		return mqueuex.ThirdPartyPaymentTradeStateRefund
// 	default:
// 		return mqueuex.ThirdPartyPaymentTradeStatePayError
// 	}
// }
